﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace WebSelfHost.Utility.HttpApi
{
    public class ProcessUtils
    {
        private static void KillProcess(string processName)
        {
            System.Diagnostics.Process myproc = new System.Diagnostics.Process();
            //得到所有打开的进程   
            try
            {
                foreach (Process thisproc in Process.GetProcessesByName(processName))
                {
                    //找到程序进程,kill之。
                    if (!thisproc.CloseMainWindow())
                    {
                        thisproc.Kill();
                    }
                }

            }
            catch (Exception Exc)
            {
                //Log.WriteLog("KillProcess", Exc.Message, LogType.Error);
            }
        }

        /// <summary>
        /// 关闭端口占用
        /// </summary>
        /// <param name="port"></param>
        public static void KillPort(int port)
        {
            Process p = new Process();
            p.StartInfo.FileName = "cmd.exe";
            p.StartInfo.UseShellExecute = false;
            p.StartInfo.RedirectStandardError = true;
            p.StartInfo.RedirectStandardInput = true;
            p.StartInfo.RedirectStandardOutput = true;
            p.StartInfo.CreateNoWindow = true;
            List<int> list_pid = GetPidByPort(p, port);
            if (list_pid.Count == 0)
            {
                return;
            }
            //List<string> list_process = GetProcessNameByPid(p, list_pid);
            //StringBuilder sb = new StringBuilder();
            //sb.AppendLine("占用" + port + "端口的进程有:");
            //foreach (var item in list_process)
            //{
            //    sb.Append(item + "\r\n");
            //}
            //sb.AppendLine("是否要结束这些进程？");

            //if (MessageBox.Show(sb.ToString(), "系统提示", MessageBoxButtons.YesNo) == DialogResult.No)
            //    return;
            PidKill(p, list_pid);

        }

        /// <summary>
        /// 停止运行
        /// </summary>
        /// <param name="processName"></param>
        public static void StopProcess(string processName)
        {
            try
            {
                System.Diagnostics.Process[] ps = System.Diagnostics.Process.GetProcessesByName(processName);
                foreach (System.Diagnostics.Process p in ps)
                {
                    p.Kill();
                }
            }
            catch (Exception ex)
            {
                //Log.WriteLog("StopProcess", ex.Message, LogType.Error);
            }
        }

        private static List<string> GetProcessNameByPid(Process p, List<int> list_pid)
        {
            p.Start();
            List<string> list_process = new List<string>();
            foreach (var pid in list_pid)
            {
                p.StandardInput.WriteLine(string.Format("tasklist |find \"{0}\"", pid));
                p.StandardInput.WriteLine("exit");
                StreamReader reader = p.StandardOutput;//截取输出流
                string strLine = reader.ReadLine();//每次读取一行

                while (!reader.EndOfStream)
                {
                    strLine = strLine.Trim();
                    if (strLine.Length > 0 && ((strLine.Contains(".exe"))))
                    {
                        Regex r = new Regex(@"\s+");
                        string[] strArr = r.Split(strLine);
                        if (strArr.Length > 0)
                        {
                            list_process.Add(strArr[0]);
                        }
                    }
                    strLine = reader.ReadLine();
                }
                p.WaitForExit();
                reader.Close();
            }
            p.Close();

            return list_process;
        }

        private static void PidKill(Process p, List<int> list_pid)
        {
            p.Start();
            foreach (var item in list_pid)
            {
                p.StandardInput.WriteLine("taskkill /pid " + item + " /f");
                p.StandardInput.WriteLine("exit");
            }
            p.Close();
        }

        private static List<int> GetPidByPort(Process p, int port)
        {
            int result;
            bool b = true;
            p.Start();
            p.StandardInput.WriteLine(string.Format("netstat -ano|find \"{0}\"", port));
            p.StandardInput.WriteLine("exit");
            StreamReader reader = p.StandardOutput;
            string strLine = reader.ReadLine();
            List<int> list_pid = new List<int>();
            while (!reader.EndOfStream)
            {
                strLine = strLine.Trim();
                if (strLine.Length > 0 && ((strLine.Contains("TCP") || strLine.Contains("UDP"))))
                {
                    Regex r = new Regex(@"\s+");
                    string[] strArr = r.Split(strLine);
                    if (strArr.Length >= 4)
                    {
                        b = int.TryParse(strArr[3], out result);
                        if (b && !list_pid.Contains(result))
                            list_pid.Add(result);
                    }
                }
                strLine = reader.ReadLine();
            }
            p.WaitForExit();
            reader.Close();
            p.Close();
            return list_pid;
        }
    }
}
